package com.example.mydemo;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.example.mydemo.utils.DatabaseTools;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TestActivity extends Activity implements View.OnClickListener {
    public TextView imb_pass,imb_fail;
    private DatabaseTools dt = null;
    private static final String TAG = "TouchScreen/HW";
    MyView mView = null;

    private int mAutoFocusState = 0;//1->focusing;2->fail;3->success
    private TextView mTestTitle;
    private int mWhitch;
    private static final int FLAG_HOMEKEY_DISPATCHED = 0x80000000;

    TextureView previewView;//预览框控件
    ImageReader previewReader;
    CameraCaptureSession cameraCaptureSession;//相机会话类
    CameraDevice cameraDevice;//相机设备类
    CameraManager cameraManager;//相机管理类
    List<Size> outputSizes;//相机输出尺寸
    Size photoSize;
    String cameraId;
    int width = 1920;
    int height = 2560;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        mWhitch = getIntent().getIntExtra("frontOrBack", 0);
        cameraId = mWhitch==1 ? "1" : "0";
        setContentView(R.layout.activity_test);
        previewView = findViewById(R.id.camera_preview);
        previewView.setSurfaceTextureListener(surfaceTextureListener);
        //初始化工具类，把Context挂载上去
        cameraManager = (CameraManager) getApplicationContext().getSystemService(Context.CAMERA_SERVICE);
        outputSizes = getCameraOutputSizes(cameraId, SurfaceTexture.class);
        for (Size size : outputSizes){
            Log.d("lfy","[TestActivity] Height="+size.getHeight()+",Width="+size.getWidth());
        }
        if (outputSizes != null){
            photoSize = outputSizes.get(0);
            width = outputSizes.get(0).getWidth();
            height = outputSizes.get(0).getHeight();
        }

        dt = new DatabaseTools(TestActivity.this);
        //测试通过
        imb_pass = (TextView)findViewById(R.id.imb_bl_pass);
        imb_pass.setOnClickListener(this);
        //测试失败
        imb_fail = (TextView)findViewById(R.id.imb_bl_fail);
        imb_fail.setOnClickListener(this);
        if(mWhitch==0) mView = new MyView(this);

        mTestTitle = (TextView) findViewById(R.id.test_tilte);
        if(mWhitch == 0){
            mTestTitle.setText(R.string.test_main_camera);
        } else {
            mTestTitle.setText(R.string.test_sub_camera);
        }
    }

    public List<Size> getCameraOutputSizes(String cameraId, Class clz){
        try {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            List<Size> sizes = Arrays.asList(configs.getOutputSizes(clz));
            Collections.sort(sizes, new Comparator<Size>() {
                @Override
                public int compare(Size o1, Size o2) {
                    return o1.getWidth() * o1.getHeight() - o2.getWidth() * o2.getHeight();
                }
            });
            Collections.reverse(sizes);
            return sizes;
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        return null;
    }

    TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            Log.d("lfy","[TestActivity] onSurfaceTextureAvailable......");
            previewView.setSurfaceTextureListener(this);
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.d("lfy","[TestActivity] onSurfaceTextureSizeChanged......");
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.d("lfy","[TestActivity] onSurfaceTextureDestroyed...");
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        }
    };

    private void configureTransform(int viewWidth, int viewHeight) {
        if (null == previewView || null == photoSize || null == this) {
            return;
        }
        int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
        RectF bufferRect = new RectF(0, 0, photoSize.getHeight(), photoSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                    (float) viewHeight / photoSize.getHeight(),
                    (float) viewWidth / photoSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        previewView.setTransform(matrix);
    }

    @SuppressLint("MissingPermission")
    private void openCamera() {
        try {
            configureTransform(previewView.getWidth(), previewView.getHeight());
            cameraManager.openCamera(cameraId,
                new CameraDevice.StateCallback() {
                    @Override
                    public void onOpened(CameraDevice camera) {
                        if (camera == null) {
                            return;
                        }
                        cameraDevice = camera;
                        //创建相机预览 session
                        createPreviewSession();
                    }
                    @Override
                    public void onDisconnected(CameraDevice camera) {
                        //释放相机资源
                        releaseImageReader(previewReader);
                        releaseCameraSession(cameraCaptureSession);
                        releaseCameraDevice(cameraDevice);
                    }

                    @Override
                    public void onError(CameraDevice camera, int error) {
                        //释放相机资源
                        releaseImageReader(previewReader);
                        releaseCameraSession(cameraCaptureSession);
                        releaseCameraDevice(cameraDevice);
                    }
                },
                null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void createPreviewSession() {
        //关闭之前的会话
        releaseImageReader(previewReader);
        releaseCameraSession(cameraCaptureSession);
        //根据TextureView 和 选定的 previewSize 创建用于显示预览数据的Surface
        SurfaceTexture surfaceTexture = previewView.getSurfaceTexture();
        Log.d("lfy","[PreviewFragment] createPreviewSession...surfaceTexture="+surfaceTexture);
        surfaceTexture.setDefaultBufferSize(width, height);//设置SurfaceTexture缓冲区大小
        final Surface previewSurface = new Surface(surfaceTexture);
        //获取 ImageReader 和 surface
        previewReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 2);
        previewReader.setOnImageAvailableListener(
                new ImageReader.OnImageAvailableListener() {
                    @Override
                    public void onImageAvailable(ImageReader reader) {
                        Image image = reader.acquireLatestImage();
                        if (image != null) {
                            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                            byte[] data = new byte[buffer.remaining()];
                            Log.d("lfy", "data-size=" + data.length);
                            buffer.get(data);
                            image.close();
                        }
                    }
                },
                null);
        final Surface readerSurface = previewReader.getSurface();

        try {
            //创建预览session
            cameraDevice.createCaptureSession(Arrays.asList(previewSurface, readerSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession session) {

                            cameraCaptureSession = session;

                            try {
                                //构建预览捕获请求
                                CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                                builder.addTarget(previewSurface);//设置 previewSurface 作为预览数据的显示界面
                                builder.addTarget(readerSurface);
                                CaptureRequest captureRequest = builder.build();
                                //设置重复请求，以获取连续预览数据
                                session.setRepeatingRequest(captureRequest, new CameraCaptureSession.CaptureCallback() {
                                            @Override
                                            public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) {
                                                super.onCaptureProgressed(session, request, partialResult);
                                            }

                                            @Override
                                            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                                                super.onCaptureCompleted(session, request, result);
                                            }
                                        },
                                        null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession session) {

                        }
                    },
                    null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    public void onPause(){
        super.onPause();
        releaseImageReader(previewReader);
        releaseCameraSession(cameraCaptureSession);
        releaseCameraDevice(cameraDevice);
        finish();
    }

    /**
     * 释放相机资源
     * @param cameraDevice
     */
    public void releaseCameraDevice(CameraDevice cameraDevice){
        if (cameraDevice != null){
            cameraDevice.close();
            cameraDevice = null;
        }
    }

    /**
     * 关闭相机会话
     * @param session
     */
    public void releaseCameraSession(CameraCaptureSession session){
        if (session != null){
            session.close();
            session = null;
        }
    }

    /**
     * 关闭 ImageReader
     * @param reader
     */
    public void releaseImageReader(ImageReader reader){
        if (reader != null){
            reader.close();
            reader = null;
        }
    }

    @Override
    public void onAttachedToWindow() {
        getWindow().addFlags(FLAG_HOMEKEY_DISPATCHED);
        super.onAttachedToWindow();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_HOME:
                releaseImageReader(previewReader);
                releaseCameraSession(cameraCaptureSession);
                releaseCameraDevice(cameraDevice);
                finish();
                return true;

            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    public void onClick(View v){
        int id = v.getId();
        if(id == R.id.imb_bl_pass){
            dt.updateResult(DatabaseTools.Db_ItTableName,mWhitch==0 ? "test_main_camera" :"test_sub_camera",2);
            finish();
        }
        else if(id == R.id.imb_bl_fail){
            dt.updateResult(DatabaseTools.Db_ItTableName,mWhitch==0 ? "test_main_camera" :"test_sub_camera",1);
            finish();
        }
    }

    public class PT {
        public Float mX;
        public Float mY;

        public PT(Float x, Float y) {
            this.mX = x;
            this.mY = y;
        }
    };

    public class MyView extends View {
        private final Paint mPaint;
        private int mCurX;
        private int mCurY;
        private int mCurWidth;

        public MyView(Context c) {
            super(c);

            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setARGB(255, 255, 255, 255);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(2);

            Display display = getWindowManager().getDefaultDisplay();
            int targetHeight = Math.min(display.getHeight(), display.getWidth());

            mCurX = (int)  (display.getWidth() / 2);
            mCurY = (int)  (display.getWidth() *3 / (4*2));
            Log.e("LyCameraTest"+TAG, "[MyView] mAutoFocusState:"+ mAutoFocusState+" ,mCurX:"+mCurX+" ,mCurY:"+mCurY);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        }

        @Override
        protected void onDraw(Canvas canvas) {
            Log.e("LyCameraTest"+TAG, "[onDraw] mAutoFocusState:"+ mAutoFocusState+" ,mCurX:"+mCurX+" ,mCurY:"+mCurY+" ,getHeight():"+getHeight());
            if(mAutoFocusState>0){
                if( mAutoFocusState==1 ) {
                    mPaint.setARGB(255,255,255,255);
                } else if(mAutoFocusState==2){
                    mPaint.setARGB(255,255,0,0);
                } else if(mAutoFocusState==3){
                    mPaint.setARGB(255,0,255,0);
                }

                mCurWidth = (int)  (getWidth() / 20);
                canvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
            }
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action = event.getAction();
            Log.e("LyCameraTest"+TAG, "onTouchEvent event: "+event );
            if (mWhitch==0 && action == MotionEvent.ACTION_DOWN) {
//                mParameters = mCamera.getParameters();
//                List<String> focusModeList = mParameters.getSupportedFocusModes();
//                //检查支持的对焦
//                if (!focusModeList.contains(Camera.Parameters.FOCUS_MODE_AUTO)){
//                    return true;
//                }
//                if (!focusModeList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
//                    return true;
//                }
//                autoFocus((int) (event.getX()),(int) (event.getY()));
            }
            mCurX = (int) event.getX();
            mCurY = (int) event.getY();

            invalidate();
            return true;
        }

        public void clear() {
            invalidate();
        }

    }
}
